package com.txq.bilibili.app.utils;

import android.content.Context;
import android.os.Environment;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by qdJack on 2015/3/11.
 */
public class FileCache {
    private static FileCache ourInstance = null;

    private Context context;

    private File fileCache;

    public static FileCache getInstance() {
        if(ourInstance == null){
            throw new IllegalStateException("FileCache must invoke createInstance(Context) before getInstance()");

        }
        return ourInstance;
    }

    public static FileCache createInstance(Context context){
        if(ourInstance == null){
            ourInstance = new FileCache(context);
        }
        return ourInstance;
    }

    private FileCache(Context context) {
        this.context = context;
        if(context != null){
            String state = Environment.getExternalStorageState();
            if(Environment.MEDIA_MOUNTED.equals(state)){
                //外部sd卡存在
                fileCache = context.getExternalCacheDir();
            }else {
                fileCache = context.getCacheDir();
            }
        }else {
            //没有上下文，只能自己用SD卡存储，一个自定义的目录离了
            String state = Environment.getExternalStorageState();
            if(Environment.MEDIA_MOUNTED.equals(state)){
                File directory = Environment.getExternalStorageDirectory();
                fileCache = new File(directory,".beyou");

            }else {
                throw new IllegalArgumentException("FileCache must set context or device has a sdcard.");
            }
        }

        if(fileCache != null){
            if(!fileCache.exists()){
                fileCache.mkdirs();
            }
        }else {
            throw new IllegalArgumentException("FileCache can't get a cache dir.");
        }
    }


    public void putContent(String url, byte[] bytes){

        if(url != null && bytes != null){
            String fileName = mapUrlToFile(url);

            File targetFile = new File(fileCache,fileName);

            boolean bok = true;
            if(!targetFile.exists()){
                try {
                    bok = targetFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(bok){
                //把数据写入到文件中
                FileOutputStream fout = null;

                try {
                    fout = new FileOutputStream(targetFile);
                    fout.write(bytes);
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(fout != null){
                        try {
                            fout.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    public byte[] getContent(String url){
        byte[] ret = null;

        if(url != null){
            String fileName = mapUrlToFile(url);

            File fileTarget = new File(fileCache,fileName);

            if(fileTarget.exists()){
                FileInputStream fis = null;
                ByteArrayOutputStream bos = null;
                try {
                    fis = new FileInputStream(fileTarget);
                    bos = new ByteArrayOutputStream();

                    byte[] bytes = new byte[128];
                    int len = 0;
                    while (true){
                        len = fis.read(bytes);
                        if(len == -1){
                            break;
                        }

                        bos.write(bytes,0,len);
                    }
                    bytes = null;
                    ret = bos.toByteArray();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if(bos != null) {
                        try {
                            bos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        return ret;

    }

    private static String mapUrlToFile(String url) {

        String ret = null;
        if(url != null){
            byte[] bytes = url.getBytes();
            if(bytes.length>0){
                try {
                    MessageDigest digest = MessageDigest.getInstance("MD5");
                    byte[] data = digest.digest(bytes);


                    ret = hex(data);

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }

            }
        }



        return ret;
    }

    private static String hex(byte[] data) {

        StringBuilder sb = new StringBuilder();

        String ret = null;
        if(data != null && data.length>0){
            for (byte b : data) {
                int h,l;
                h = (b>>4) & 0x0f;
                l = b & 0x0f;
                sb.append(Integer.toHexString(h));
                sb.append(Integer.toHexString(l));
            }

            ret = sb.toString();
        }

        return ret;
    }
}
